<template>
  <div class="markdown">
    <div class="editor-head">
      <div class="editor-head-inner">
        <!--标题输入-->
        <el-input
            show-word-limit
            class="editor-title"
            size="large"
            placeholder="请输入标题..."
            v-model="article.title"
            maxlength="50">
        </el-input>
        <!--文章细节输入-->
        <el-button type="primary" @click="openDialog">发布文章</el-button>
        <el-dialog
            v-model="state.visible"
            width="40%"
            title="发布文章"
            align-center
            :close-on-click-modal="false"
            :before-close="onClose"
            :show-close="false"
        >
          <div class="publish-form">
            <el-form label-position="left" ref="ruleFormRef" :model="article" :rules="rules">

              <el-form-item label="分类" prop="clazz">
                <el-radio-group v-model="article.clazz" size="default">
                  <el-radio-button label="后端"/>
                  <el-radio-button label="前端"/>
                  <el-radio-button label="游戏"/>
                  <el-radio-button label="算法"/>
                  <el-radio-button label="生活"/>
                </el-radio-group>
              </el-form-item>

              <el-form-item label="标签" prop="label">
                <el-input
                    style="width: 56%"
                    v-model="article.label"
                    maxlength="10"
                    show-word-limit
                    placeholder="输入自定义标签..."/>
              </el-form-item>

              <el-form-item label="封面" prop="cover">
                <el-upload
                    action="#"
                    :limit="1"
                    :on-exceed="onExceed"
                    :file-list="state.fileList"
                    list-type="picture-card"
                    :show-file-list="true"
                    :before-upload="onBeforeUpload"
                    :http-request="onUploadCover">
                  <el-icon>
                    <Plus/>
                  </el-icon>
                </el-upload>
              </el-form-item>

              <el-form-item label="摘要" prop="summary">
                <el-input
                    maxlength="100"
                    show-word-limit
                    type="textarea"
                    rows="5"
                    resize="none"
                    v-model="article.summary"></el-input>
              </el-form-item>
            </el-form>
          </div>
          <template v-slot:footer>
            <el-button @click="closeDialog">取消发布</el-button>
            <el-button type="primary" @click="onPublish(ruleFormRef)">确认发布</el-button>
          </template>
        </el-dialog>
      </div>
    </div>
    <md-editor
        :toolbars-exclude="toolBarExclude"
        :on-upload-img="onUpload"
        :on-save="onSave"
        placeholder="# hello world"
        v-model="article.content"
        preview-theme="vuepress"
        class="editor"/>
  </div>
</template>

<script setup lang="ts">
import MdEditor from "md-editor-v3";
import "md-editor-v3/lib/style.css";
import {reactive, ref} from "vue";
import {Message} from "@/utils/Message";
import {UploadService} from "@/service/file";
import {BusinessCode} from "@/lang/Common";
import {ArticleInfo} from "@/entity/article/article";
import {Plus} from "@element-plus/icons-vue";
import {FormInstance, FormRules, UploadRequestOptions} from "element-plus";
import {CreateArticle} from "@/service/article";
import router from "@/router";

const ruleFormRef = ref<FormInstance>();
const toolBarExclude = [
  "htmlPreview",
];

const tempKey = "articleTemp";
let cache = localStorage.getItem(tempKey);
let stateinit: ArticleInfo;
if (cache !== null) {
  stateinit = JSON.parse(cache);
} else {
  stateinit = {
    title: "",
    author: "",
    cover: "",
    clazz: "",
    label: "",
    content: "",
    summary: ""
  };
}

const article = reactive<ArticleInfo>(stateinit);
const state = reactive({
  visible: false,
  fileList: []
});

const openDialog = () => {
  state.visible = true;
};
const closeDialog = () => {
  state.visible = false;
};

// 保存在本地
const onSave = function (v: string, h: Promise<string>) {
  localStorage.setItem(tempKey, JSON.stringify(article));
  Message.success("本地保存成功");
};

const rules = reactive<FormRules>({
  clazz: [
    {
      required: true,
      message: "请选择分类",
      trigger: "blur"
    }
  ],
  label: [
    {
      required: true,
      message: "请输入标签",
      trigger: "blur"
    }
  ],
  summary: [
    {
      required: true,
      message: "请输入摘要",
      trigger: "blur"
    }
  ]
});

const check = (): boolean => {
  if (article.title == undefined || article.title.length === 0) {
    Message.error("请输入文章标题");
    return false;
  } else if (article.content == undefined || article.content.length === 0) {
    Message.error("请输入文章内容");
    return false;
  }
  return true;
};
// 上传图片
const onUpload = function (files: Array<File>, callback: (url: string[]) => void) {
  let form = new FormData();
  for (let i = 0; i < files.length; i++) {
    form.append("file", files[i]);
  }
  UploadService(form).then(res => {
    if (res?.data?.code === BusinessCode.Ok) {
      let url: string[] = [];
      // eslint-disable-next-line no-undef
      res.data.data.forEach((value) => {
        url.push("http://localhost:8080/v1/static/" + value.url);
      });
      callback(url);
    }
  });
};

//  发布文章回调
const onPublish = (formEl: FormInstance | undefined) => {
  formEl?.validate((isValid: boolean) => {
    if (isValid && check()) {
      CreateArticle(article).then(res => {
        if (res?.data?.code == BusinessCode.Ok) {
          router.replace({name: "list"});
          Message.success(res.data.msg);
          // 删除本地缓存
          localStorage.removeItem(tempKey);
        }
      });
    }
  });
};

const onExceed = () => {
  Message.warning("只能上传一个文章封面");
};

const onClose = (done: () => void) => {
  done();
};

// 上传封面
const onUploadCover = (option: UploadRequestOptions) => {
  let file = option.file;
  let form = new FormData();
  form.append("file", file);
  UploadService(form).then(res => {
    if (res?.data?.code === BusinessCode.Ok) {
      article.cover = res.data.data[0].url;
    }
  });
};

// 文件上传前校验
const onBeforeUpload = (file: File): boolean => {
  if (!["image/png", "image/webp", "image/jpg", "image/jpeg"].includes(file.type)) {
    Message.error("仅支持png，webp，jpg，jpeg格式");
    return false;
  } else if (file.size >= 5 * 1024 * 1024) {
    Message.error("图片大小不能超过5MB");
    return false;
  } else {
    return true;
  }
};

</script>

<style scoped>
.markdown {
  background: white;
}

.editor-head {
  height: 5vh;
  display: flex;
  align-items: center;
  justify-content: center;
}

.editor-head-inner {
  width: 100%;
}

.editor-title {
  width: 50%;
  margin-right: 20px;
}

.editor {
  height: 95vh;
  text-align: left;
}

.publish-form {
  margin: 0 30px;
}

:deep(.el-upload-list__item-preview) {
  display: none !important;
}

:deep(.el-dialog) {
  border-radius: 1%;
}

:deep(.el-dialog__body) {
  border-bottom: 0.5px solid rgb(229, 230, 235);
  border-top: 0.5px solid rgb(229, 230, 235);
}

:deep(.el-radio-button__inner) {
  padding: 8px 16px;
}

.upload-cover {
  width: 100%;
}
</style>
